package main

import (
	"errors"
	"io"
	"os"
	"path/filepath"
	"strings"
)

// New方法错误信息要求小写开头
var ErrEmptyFile = errors.New("error: Empty File")

func CountLines(path string) (*Count, error) {
	count := &Count{
		// 根据.号，删掉.号的所有前缀，留下扩展名
		//https://blog.csdn.net/yzf279533105/article/details/106212392
		Ext: strings.ToLower(strings.TrimPrefix(
			filepath.Ext(path),
			".",
		)),
		FileCount: 1,
	}

	file, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	// 关闭文件
	defer func() {
		_ = file.Close()
	}()

	stat, err := file.Stat()
	if err != nil {
		return nil, err
	}

	// 文件一个字节都没有
	if stat.Size() <= 0 {
		return nil, ErrEmptyFile
	}

	buf := make([]byte, 8196)
	emptyLine := true

	for {
		// 对文件读入buf大小
		n, err := file.Read(buf)
		if err != nil && err != io.EOF {
			return count, err
		}

		for _, c := range buf[:n] {
			switch c {
			case 0x0: // 空
				count.Blank = 0
				count.Code = 0
				count.FileCount = 0
				count.Binary = 1
				return count, nil
			case '\n':
				if emptyLine {
					count.Blank++
				} else {
					count.Code++
				}
				emptyLine = true
			case '\r', ' ', '\t': // ignore
			default:
				emptyLine = false
			}
		}
		if err == io.EOF {
			break
		}
	}

	if !emptyLine {
		count.Code++
	}

	return count, nil
}
